home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / main.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  11KB  |  398 lines

  1. /*
  2.  * Initializes everything and starts a calendar window for the current
  3.  * month. The interval timer (for autosave and entry recycling) and a
  4.  * few routines used by everyone are also here.
  5.  *
  6.  *    main(argc, argv)        Guess.
  7.  *
  8.  * Author: thomas@bitrot.in-berlin.de (Thomas Driemeyer)
  9.  */
  10.  
  11. #include "config.h"
  12. #include <X11/Xos.h>
  13. #include <stdio.h>
  14. #include <sys/stat.h>
  15. #include <errno.h>
  16. #include <Xm/Xm.h>
  17. #include <X11/StringDefs.h>
  18. #include "grok.h"
  19. #include "form.h"
  20. #include "proto.h"
  21. #include "patchlevel.h"
  22.  
  23. static void usage(void), mkdir_callback(void), make_grokdir(void);
  24. static void init_colors(void), init_fonts(void), init_pixmaps(void);
  25.  
  26. extern CARD         *curr_card;    /* card switched to if -t */
  27. extern Widget        w_summary;    /* form for summary table */
  28. extern Widget        mainwindow;    /* popup menus hang off main window */
  29. Display            *display;    /* everybody uses the same server */
  30. GC            gc;        /* everybody uses this context */
  31. GC            xor_gc;        /* XOR gc for rubberbanding */
  32. XtAppContext        app;        /* application handle */
  33. Widget            toplevel;    /* top-level shell for icon name */
  34. char            *progname;    /* argv[0] */
  35. XFontStruct        *font[NFONTS];    /* fonts: FONT_* */
  36. XmFontList        fontlist[NFONTS];
  37. Pixel            color[NCOLS];    /* colors: COL_* */
  38. Pixmap            pixmap[NPICS];    /* common symbols */
  39. BOOL            restricted;    /* restricted mode, no form editor */
  40.  
  41.  
  42. static String fallbacks[] = {
  43. #include "resource.h"
  44.     NULL
  45. };
  46.  
  47.  
  48. /*
  49.  * initialize everything and create the main calendar window
  50.  */
  51.  
  52. int main(
  53.     int        argc,
  54.     char        *argv[])
  55. {
  56.     int        n, i;
  57.     char        *formname = 0;
  58.     char        *query = 0;
  59.     BOOL        nofork = FALSE;
  60.     BOOL        ttymode = FALSE;
  61.     BOOL        noheader = FALSE;
  62.     XGCValues    gcval;
  63.  
  64.     if ((progname = strrchr(argv[0], '/')) && progname[1])
  65.         progname++;
  66.     else
  67.         progname = argv[0];
  68.     restricted = !strcmp(progname, "rgrok");
  69.  
  70.     for (n=1; n < argc; n++)            /* options */
  71.         if (*argv[n] != '-')
  72.             if (!formname)
  73.                 formname = argv[n];
  74.             else if (!query)
  75.                 query = argv[n];
  76.             else
  77.                 usage();
  78.  
  79.         else if (argv[n][2] < 'a' || argv[n][2] > 'z')
  80.             switch(argv[n][1]) {
  81.               case 'd':
  82.                 for (i=0; fallbacks[i]; i++)
  83.                     printf("%s%s\n", progname,
  84.                              fallbacks[i]);
  85.                 fflush(stdout);
  86.                 return(0);
  87.               case 'v':
  88.                 fprintf(stderr, "%s: %s\n", progname, VERSION);
  89.                 return(0);
  90.               case 'f':
  91.                 nofork = TRUE;
  92.                 break;
  93.               case 'T':
  94.                 noheader = TRUE;
  95.               case 't':
  96.                 ttymode = TRUE;
  97.                 break;
  98.               case 'r':
  99.                 restricted = TRUE;
  100.                 break;
  101.               default:
  102.                 usage();
  103.             }
  104.  
  105.     (void)umask(0077);
  106.     tzset();
  107.     if (ttymode) {
  108.         char buf[1024];
  109.         if (!formname)
  110.             usage();
  111.         read_preferences();
  112.         switch_form(formname);
  113.         if (!curr_card ||!curr_card->dbase ||!curr_card->dbase->nrows){
  114.             fprintf(stderr, "%s: %s: no data\n",progname,formname);
  115.             _exit(0);
  116.         }
  117.         query_any(curr_card, query);
  118.         if (!curr_card->nquery) {
  119.             fprintf(stderr,"%s: %s: no match\n",progname,formname);
  120.             _exit(0);
  121.         }
  122.         if (!noheader) {
  123.             char *p;
  124.             make_summary_line(buf, curr_card, -1);
  125.             puts(buf);
  126.             for (p=buf; *p; p++)
  127.                 *p = '-';
  128.             puts(buf);
  129.         }
  130.         for (n=0; n < curr_card->nquery; n++) {
  131.             make_summary_line(buf, curr_card, curr_card->query[n]);
  132.             puts(buf);
  133.         }
  134.         fflush(stdout);
  135.         _exit(0);
  136.     }
  137.     if (!nofork) {                    /* background */
  138.         long pid = fork();
  139.         if (pid < 0)
  140.             perror("can't fork");
  141.         else if (pid > 0)
  142.             _exit(0);
  143.     }
  144.     toplevel = XtAppInitialize(&app, "Grok", NULL, 0,
  145. #        ifndef XlibSpecificationRelease
  146.                 (Cardinal *)&argc, argv,
  147. #        else
  148.                 &argc, argv,
  149. #        endif
  150.                 fallbacks, NULL, 0);
  151.     display = XtDisplay(toplevel);
  152.     set_icon(toplevel, 0);
  153.     gc     = XCreateGC(display, DefaultRootWindow(display), 0, 0);
  154.     xor_gc = XCreateGC(display, DefaultRootWindow(display), 0, 0);
  155.     gcval.function = GXxor;
  156.     (void)XChangeGC(display, xor_gc, GCFunction, &gcval);
  157.     XSetForeground(display, xor_gc,
  158.             WhitePixelOfScreen(DefaultScreenOfDisplay(display)));
  159.  
  160.     init_colors();
  161.     init_fonts();
  162.     init_pixmaps();
  163.     read_preferences();
  164.     XSetForeground(display, xor_gc, color[COL_CANVBACK]);
  165.  
  166.     create_mainwindow(toplevel);
  167.     XtRealizeWidget(toplevel);
  168.  
  169.     make_grokdir();
  170.  
  171.     if (formname)
  172.         switch_form(formname);
  173.     if (query) {
  174.         query_any(curr_card, query);
  175.         create_summary_menu(curr_card, w_summary, mainwindow);
  176.         curr_card->row = curr_card->query ? curr_card->query[0]
  177.                           : curr_card->dbase->nrows;
  178.         fillout_card(curr_card, FALSE);
  179.     }
  180.     XtAppMainLoop(app);
  181.     return(0);
  182. }
  183.  
  184.  
  185. /*
  186.  * usage information
  187.  */
  188.  
  189. static void usage(void)
  190. {
  191.     fprintf(stderr, "Usage: %s [options] [form ['query']]\n", progname);
  192.     fprintf(stderr, "    Options:\n%s%s%s%s%s%s%s\n",
  193.             "\t-h\tprint this help text\n",
  194.             "\t-d\tdump fallback app-defaults and exit\n",
  195.             "\t-v\tprint version string\n",
  196.             "\t-t\tprint cards matching query to stdout\n",
  197.             "\t-T\tsame as -t without header line\n",
  198.             "\t-f\tdon't fork on startup\n",
  199.             "\t-r\trestricted, disable form editor (rgrok)\n");
  200.     fprintf(stderr, "    the form argument is required for -t and -T.\n");
  201.     _exit(1);
  202. }
  203.  
  204.  
  205. /*
  206.  * create the directory that holds all forms and databases. This is a
  207.  * separate routine to avoid having a big buffer on the stack in main().
  208.  */
  209.  
  210. static void mkdir_callback(void)
  211. {
  212.     char *path = resolve_tilde(GROKDIR, 0);
  213.     (void)chmod(path, 0700);
  214.     (void)mkdir(path, 0700);
  215.     if (access(path, X_OK))
  216.         create_error_popup(toplevel, errno,
  217.                     "Cannot create directory %s", path);
  218. }
  219.  
  220. static void make_grokdir(void)
  221. {
  222.     char *path = resolve_tilde(GROKDIR, 0);
  223.     if (access(path, X_OK))
  224.         create_query_popup(toplevel, mkdir_callback, 0,
  225. "Cannot access directory %s\n\n\
  226. This directory is required to store the grok configuration\n\
  227. file, and it is the default location for forms and databases.\n\
  228. If you are running grok for the first time and intend to use it\n\
  229. regularly, press OK now and copy all files from the grokdir\n\
  230. demo directory in the grok distribution into %s .\n\
  231. \n\
  232. If you want to experiment with grok first, press Cancel. If\n\
  233. you have a grokdir directory in the directory you started\n\
  234. grok from, it will be used in place of %s, but you may\n\
  235. not be able to create new forms and databases, and con-\n\
  236. figuration changes will not be saved.",
  237.                         path, GROKDIR, GROKDIR);
  238. }
  239.  
  240.  
  241. /*------------------------------------ init ---------------------------------*/
  242. /*
  243.  * read resources and put them into the config struct. This routine is used
  244.  * for getting three types of resources: res_type={XtRInt,XtRBool,XtRString}.
  245.  */
  246.  
  247. void get_rsrc(
  248.     void        *ret,
  249.     char        *res_name,
  250.     char        *res_class_name,
  251.     char        *res_type)
  252. {
  253.     XtResource    res_list[1];
  254.  
  255.     res_list->resource_name      = res_name;
  256.     res_list->resource_class  = res_class_name;
  257.     res_list->resource_type      = res_type;
  258.     res_list->resource_size      = sizeof(res_type);
  259.     res_list->resource_offset = 0;
  260.     res_list->default_type      = res_type;
  261.     res_list->default_addr      = 0;
  262.  
  263.     XtGetApplicationResources(toplevel, ret, res_list, 1, NULL, 0);
  264. }
  265.  
  266.  
  267. /*
  268.  * determine all colors, and allocate them. They can then be used by a call
  269.  * to set_color(COL_XXX).
  270.  */
  271.  
  272. static void init_colors(void)
  273. {
  274.     Screen            *screen = DefaultScreenOfDisplay(display);
  275.     Colormap        cmap;
  276.     XColor            rgb;
  277.     int            i, d;
  278.     char            *c, *n, class_name[256];
  279.  
  280.     cmap = DefaultColormap(display, DefaultScreen(display));
  281.     for (i=0; i < NCOLS; i++) {
  282.         switch (i) {
  283.           default:
  284.           case COL_STD:        n = "colStd";        d=1;    break;
  285.           case COL_BACK:    n = "colBack";        d=0;    break;
  286.           case COL_SHEET:    n = "colSheet";        d=0;    break;
  287.           case COL_TEXTBACK:    n = "colTextBack";    d=0;    break;
  288.           case COL_TOGGLE:    n = "colToggle";    d=1;    break;
  289.           case COL_CANVBACK:    n = "colCanvBack";    d=0;    break;
  290.           case COL_CANVFRAME:    n = "colCanvFrame";    d=1;    break;
  291.           case COL_CANVBOX:    n = "colCanvBox";    d=0;    break;
  292.           case COL_CANVSEL:    n = "colCanvSel";    d=1;    break;
  293.           case COL_CANVTEXT:    n = "colCanvText";    d=1;    break;
  294.           case COL_CHART_AXIS:    n = "colChartAxis";    d=1;    break;
  295.           case COL_CHART_GRID:    n = "colChartGrid";    d=1;    break;
  296.           case COL_CHART_BOX:    n = "colChartBox";    d=1;    break;
  297.           case COL_CHART_0:    n = "colChart0";    d=0;    break;
  298.           case COL_CHART_1:    n = "colChart1";    d=0;    break;
  299.           case COL_CHART_2:    n = "colChart2";    d=0;    break;
  300.           case COL_CHART_3:    n = "colChart3";    d=0;    break;
  301.           case COL_CHART_4:    n = "colChart4";    d=0;    break;
  302.           case COL_CHART_5:    n = "colChart5";    d=0;    break;
  303.           case COL_CHART_6:    n = "colChart6";    d=0;    break;
  304.           case COL_CHART_7:    n = "colChart7";    d=0;    break;
  305.         }
  306.         strcpy(class_name, n);
  307.         class_name[0] &= ~('a'^'A');
  308.         get_rsrc(&c, n, class_name, XtRString);
  309.         if (!XParseColor(display, cmap, c, &rgb))
  310.             fprintf(stderr, "%s: unknown color \"%s\" (%s)\n",
  311.                             progname, c, n);
  312.         else if (!XAllocColor(display, cmap, &rgb))
  313.             fprintf(stderr, "%s: can't alloc color \"%s\" (%s)\n",
  314.                             progname, c, n);
  315.         else {
  316.             color[i] = rgb.pixel;
  317.             continue;
  318.         }
  319.         color[i] = d ? BlackPixelOfScreen(screen)
  320.                  : WhitePixelOfScreen(screen);
  321.     }
  322. }
  323.  
  324.  
  325. void set_color(
  326.     int        col)
  327. {
  328.     XSetForeground(display, gc, color[col]);
  329. }
  330.  
  331.  
  332. /*
  333.  * load all fonts and make them available in the "fonts" struct. They are
  334.  * loaded into the GC as necessary.
  335.  */
  336.  
  337. static void init_fonts(void)
  338. {
  339.     int        i;
  340.     char        *f, class_name[256];
  341.  
  342.     for (i=0; i < NFONTS; i++) {
  343.         switch (i) {
  344.           default:
  345.           case FONT_STD:    f = "fontList";            break;
  346.           case FONT_HELP:    f = "helpFont";            break;
  347.           case FONT_HELV:    f = "helvFont";            break;
  348.           case FONT_HELV_O:    f = "helvObliqueFont";        break;
  349.           case FONT_HELV_S:    f = "helvSmallFont";        break;
  350.           case FONT_HELV_L:    f = "helvLargeFont";        break;
  351.           case FONT_COURIER:    f = "courierFont";        break;
  352.           case FONT_LABEL:    f = "labelFont";        break;
  353.         }
  354.         strcpy(class_name, f);
  355.         class_name[0] &= ~('a'^'A');
  356.         get_rsrc(&f, f, class_name, XtRString);
  357.         if (!(font[i] = XLoadQueryFont(display, f)))
  358.             fatal("can't load font \"%s\"\n", f);
  359.         if (!(fontlist[i] = XmFontListCreate(font[i], "cset")))
  360.             fatal("can't create fontlist \"%s\"\n", f);
  361.     }
  362. }
  363.  
  364.  
  365. /*
  366.  * allocate pixmaps
  367.  */
  368.  
  369. #include "bm_left.h"
  370. #include "bm_right.h"
  371.  
  372. static unsigned char *pics[NPICS] = { bm_left_bits,   bm_right_bits };
  373. static int pix_width[NPICS]      = { bm_left_width,  bm_right_width };
  374. static int pix_height[NPICS]      = { bm_left_height, bm_right_height };
  375.  
  376. static void init_pixmaps(void)
  377. {
  378.     int            p;
  379.     Colormap        cmap;
  380.     XColor            rgb;
  381.     char            *c;
  382.  
  383.     cmap = DefaultColormap(display, DefaultScreen(display));
  384.     get_rsrc(&c, "background", "Background", XtRString);
  385.     if (!XParseColor(display, cmap, c, &rgb))
  386.         fprintf(stderr, "pixmap error: unknown bkg color \"%s\"\n", c);
  387.     if (!XAllocColor(display, cmap, &rgb))
  388.         fprintf(stderr, "pixmap error: can't alloc bkg color \"%s\"\n",
  389.                                     c);
  390.     for (p=0; p < NPICS; p++)
  391.         if (!(pixmap[p] = XCreatePixmapFromBitmapData(display,
  392.                 DefaultRootWindow(display),
  393.                 (char *)pics[p], pix_width[p], pix_height[p],
  394.                 color[COL_STD], rgb.pixel,
  395.                 DefaultDepth(display,DefaultScreen(display)))))
  396.             fatal("no memory for pixmaps");
  397. }
  398.